<?php

namespace Core;

use Yaf\Registry;

/**
 * 基于Yaf封装的DI容器
 * Class Di
 * @package Core
 */
class Di
{
    private function __construct()
    {
    }

    private function __clone()
    {
    }

    /**块赋值
     * @param $object
     * @param array $properties
     * @author Jiang Haiqiang
     * @email  jhq0113@163.com
     */
    public static function block($object,$properties=[])
    {
        foreach ($properties as $property => $value) {
            $object->$property = $value;
        }
    }

    /**根据对象配置创建对象
     * $config中必须有class节点，表示对象的类型
     * @param array  $config   对象配置
     * @return mixed
     */
    public static function createObject($config)
    {
        $class = $config['class'];
        unset($config['class']);

        $object = new $class();

        self::block($object,$config);

        if(method_exists($object,'init')) {
            $object->init();
        }

        return $object;
    }

    /**
     * 放入容器
     * @param string $name
     * @param mixed  $config
     * @return bool
     */
    public static function set($name,$config)
    {
        return Registry::set($name,$config);
    }

    /**
     * 从容器中个取出
     * 如果$name已经被实例化，直接返回，若未被实例化，则实例化放入容器并返回
     * @param $name
     * @return static
     */
    public static function get($name)
    {
        $object = Registry::get($name);
        if(is_array($object) && isset($object['class'])) {
            $instance = self::createObject($object);
            Registry::set($name,$instance);
            return $instance;
        }

        return $object;
    }

    /**
     * 动态组件
     * @param mixed        $config
     * @param null|string  $defaultClass
     * @return array|mixed
     */
    public static function insure($config,$defaultClass=null)
    {
        if(is_array($config)) {
            if(isset($config['class'])) {
                return self::createObject($config);
            }

            if(isset($defaultClass)) {
                $config['class'] = $defaultClass;

                return self::createObject($config);
            }
        }

        return $config;
    }

}